//
//  ZSRefreshControl.swift
//  WB
//
//  Created by macssss on 16/7/9.
//  Copyright © 2016年 macssss. All rights reserved.
//

import UIKit

//刷新临界点 常数值
private let ZSRefreshOffset: CGFloat = 126

/// - Normal:      普通状态，什么都不做
/// - Pulling:     超过临界点，如果放手，开始刷新
/// - WillRefresh: 用户超过临界点，并且放手
//定义刷新状态 枚举
enum ZSRefreshState {
    
    //默认状态 ，什么都不做
    case Normal
    //超过临界点，如果放手 刷新
    case Pulling
    //超过临界点并且放手
    case WillRefresh
    
}

    //MARK: - 刷新控件的 逻辑处理
class ZSRefreshControl: UIControl {

    private weak var scrollView: UIScrollView?
    
 
    private lazy var refreshView: ZSRefreshView = ZSRefreshView.refreshView()
    
    init() {
        super.init(frame: CGRect())
        
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
       super.init(coder: aDecoder)
        
        setupUI()
    }
    
    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        
        print(newSuperview)
        
        guard let sv = newSuperview as? UIScrollView else {
            
            return
        }
        
        scrollView = sv
        
        scrollView?.addObserver(self, forKeyPath: "contentOffset", options: [], context: nil)
        
    }
    
    
    // 本视图从父视图上移除
    // 提示：所有的下拉刷新框架都是监听父视图的 contentOffset
    // 所有的框架的 KVO 监听实现思路都是这个！
    override func removeFromSuperview() {
        //从父视图删除KVO观察者
        superview?.removeObserver(self, forKeyPath: "contentOffset")
        
        super.removeFromSuperview()
    }

    //所有KVO 方法都会统一调用这个方法
    //一般只监听几个方法 监听怠惰会很乱
    // 观察者模式，在不需要的时候，都需要释放
    // - 通知中心：如果不释放，什么也不会发生，但是会有内存泄漏，会有多次注册的可能！
    // - KVO：如果不释放，会崩溃！

    override func observeValue(forKeyPath keyPath: String?, of object: AnyObject?, change: [NSKeyValueChangeKey : AnyObject]?, context: UnsafeMutablePointer<Void>?) {
        
        guard let sv = scrollView else {
            return
        }
        
        let height =  -(sv.contentInset.top + sv.contentOffset.y)
        
        if height < 0 {
            return
        }
        
        self.frame = CGRect(x: 0,
                            y: -height,
                            width: sv.bounds.width,
                            height: height)
        
        refreshView.parentViewHeigth = height
        
        if sv.isDragging {
            
            if height > ZSRefreshOffset && (refreshView.refreshState == .Normal) {
                
                print("放手刷新")
                refreshView.refreshState = .Pulling
                
            } else if height <= ZSRefreshOffset && (refreshView.refreshState == .Pulling ) {
                print("继续使劲…………")
            //判断状态，如果不是正在刷新 直接返回
               refreshView.refreshState = .Normal
            }
    
        } else {
            
            //判断放手是否到临界点 刷新
            if refreshView.refreshState == .Pulling {
                
                // 调用刷新还是
                beginRefreshing()
                //发送刷新数据事件
                sendActions(for: .valueChanged)
            }
        }
    }
    
  
    func beginRefreshing() {
        
        print("开始刷新")
        guard let sv = scrollView else {
            return
        }
        
        if refreshView.refreshState == .WillRefresh {
            return
        }
        
        //设置刷新的状态
        refreshView.refreshState = .WillRefresh
        
        var inset = sv.contentInset
        inset.top += ZSRefreshOffset
        
        sv.contentInset = inset
        
        refreshView.parentViewHeigth = ZSRefreshOffset
    }
    
  
  func endRefreshing() {
    
    guard let sv = scrollView else {
        return
    }
    
    // 判断状态，是否正在刷新，如果不是，直接返回
    if refreshView.refreshState != .WillRefresh {
        return
    }
    
    // 恢复刷新视图的状态
    refreshView.refreshState = .Normal
    
    // 恢复表格视图的 contentInset
    var inset = sv.contentInset
    inset.top -= ZSRefreshOffset
    
    sv.contentInset = inset
  }

}

//MARK: - 刷新控件 布局
extension ZSRefreshControl {
    
    private func setupUI() {
     
        backgroundColor = superview?.backgroundColor
        
        // 设置超出边界不显示
//        clipsToBounds = true
        

        addSubview(refreshView)
        
        
        refreshView.translatesAutoresizingMaskIntoConstraints = false
        
        // 自动布局 - 设置 xib 控件的自动布局，需要指定宽高约束
        // 提示：iOS 程序员，一定要会原生的写法，因为：如果自己开发框架，不能用任何的自动布局框架！
        addConstraint(NSLayoutConstraint(item: refreshView,
                                         attribute: .centerX,
                                         relatedBy: .equal,
                                         toItem: self,
                                         attribute: .centerX,
                                         multiplier: 1.0,
                                         constant: 0))
        addConstraint(NSLayoutConstraint(item: refreshView,
                                         attribute: .bottom,
                                         relatedBy: .equal,
                                         toItem: self,
                                         attribute: .bottom,
                                         multiplier: 1.0,
                                         constant: 0))
        addConstraint(NSLayoutConstraint(item: refreshView,
                                         attribute: .width,
                                         relatedBy: .equal,
                                         toItem: nil,
                                         attribute: .notAnAttribute,
                                         multiplier: 1.0,
                                         constant: refreshView.bounds.width))
        addConstraint(NSLayoutConstraint(item: refreshView,
                                         attribute: .height,
                                         relatedBy: .equal,
                                         toItem: nil,
                                         attribute: .notAnAttribute,
                                         multiplier: 1.0,
                                         constant: refreshView.bounds.height))
        

   }
}












